﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Description;
using FingerPrintRecognizer.Common;

namespace FRServiceHost
{
    public partial class FPRHostPanel : Form
    {
        #region Fields
        ServiceHost host;
        FingerPrintRecognizer.FPRecognizerService instance;
        string currentPluginPath = ".";
        PluginInfo[] plugins;
        TextBoxLogger logger;
        #endregion

        public FPRHostPanel()
        {
            InitializeComponent();
            logger = new TextBoxLogger(this.textBox1);
            button1.Enabled = true;
            button2.Enabled = false;
            instance = new FingerPrintRecognizer.FPRecognizerService(logger,currentPluginPath);
            updatePluginList();
        }

        #region Methods
        private void printPluginInfo(PluginInfo pi)
        {
            logger.info("============================================================");
            logger.info(" PluginInfo: " + pi.PluginName);
            logger.info("============================================================");
            logger.info("Author: " + pi.PluginAuthor);
            logger.info("Type: " + pi.Type);
            logger.info("Version: " + pi.Version);
            logger.info("Assembly Path:" + pi.DLLPath);
            logger.info("Class:" + pi.ClassName);
            logger.info("Description: " + pi.Description);
        }

        private void updatePluginList()
        {
            this.plugins = instance.getPluginList();
            cmb_algPluginList.Items.Clear();
            cmb_dbPluginList.Items.Clear();

            foreach (PluginInfo p in plugins)
            {
                logger.debug("Plugin found: " + p);
                if (p.Type == PluginInfo.PluginType.DataLayer) cmb_dbPluginList.Items.Add(p);
                else cmb_algPluginList.Items.Add(p);
            }

            if (cmb_algPluginList.Items.Count > 0) cmb_algPluginList.SelectedIndex = 0;
            if (cmb_dbPluginList.Items.Count > 0) cmb_dbPluginList.SelectedIndex = 0;
        }

        void loadSelectedPlugins() {
            PluginInfo pi = cmb_algPluginList.SelectedItem as PluginInfo;
            if (null == pi) logger.warn("No plugin has been selected for Algorithm");
            else if (instance.loadPlugin(pi)) logger.info(String.Format("Plugin {0}Loaded successfully!!!", pi));
            else logger.err("Could not load plugin " + pi);

            pi = cmb_dbPluginList.SelectedItem as PluginInfo;
            if (null == pi) logger.warn("No plugin has been selected for Database");
            else if (instance.loadPlugin(pi)) logger.info(String.Format("Plugin {0}Loaded successfully!!!", pi));
            else logger.err("Could not load plugin " + pi);
        }

        #endregion

        #region Event Handlers
        private void btn_refresh_Click(object sender, EventArgs e)
        {
            this.updatePluginList();
        }

        private void plgPath_SelectedIndexChanged(object sender, EventArgs e)
        {
            currentPluginPath = plgPath.Text;
            if (null != instance) instance.PluginDir = currentPluginPath;
        }

        private void btn_showPluginInfo_Click(object sender, EventArgs e)
        {
            PluginInfo pi = cmb_algPluginList.SelectedItem as PluginInfo;
            if (null == pi) logger.warn("No plugin has been selected for Algorithm");
            else printPluginInfo(pi);

            pi = cmb_dbPluginList.SelectedItem as PluginInfo;
            if (null == pi) logger.warn("No plugin has been selected for Database");
            else printPluginInfo(pi);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            loadSelectedPlugins();
            try
            {
                if (host != null)
                {
                    host.Close();
                }

                Uri baseAddress = new Uri(textBox2.Text);

                host = new ServiceHost(instance, baseAddress);

                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);

                WSHttpBinding binding = new WSHttpBinding();
                host.AddServiceEndpoint(typeof(FingerPrintRecognizer.IFPRecognizerService), binding, "");

                host.Open();
                logger.info(" WCF: Host open successfully \n");


                button1.Enabled = false;
                button2.Enabled = true;

                logger.info(" WCF: Service Started successfully \n");
            }
            catch (Exception ex)
            {
                logger.err(String.Format("WCF: Error in  opening Host : {1}\n", ex.Message));

                if (host != null)
                {
                    host = null;
                }
            }


        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                if (host != null)
                {
                    host.Close();
                    host = null;

                    logger.info(" WCF: Host close successfully \n");
                    logger.info(" WCF: Stopped successfully \n");


                }
            }
            catch (Exception ex)
            {

                logger.err(String.Format("WCF: Error in closing Host : {1}\n", ex.Message));
            }

            button1.Enabled = true;
            button2.Enabled = false;

        }

        private void btn_choosePluginDir_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK == pluginDirChooser.ShowDialog())
            {
                currentPluginPath = pluginDirChooser.SelectedPath;
                plgPath.Text = currentPluginPath;
                if (null != instance) instance.PluginDir = currentPluginPath;
            }

        }

        #endregion
    }
}